package no.uib.mitraq.gui;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import no.uib.mitraq.util.Export;
import no.uib.mitraq.util.ImageType;
import org.apache.batik.transcoder.TranscoderException;
import org.jfree.chart.ChartPanel;

/**
 * Simple dialog for selecting the image type to export the plot to.
 *
 * @author Harald Barsnes
 */
public class ExportPlot extends javax.swing.JDialog implements ProgressDialogParent {

    /**
     * The progress dialog.
     */
    private ProgressDialog progressDialog;
    /**
     * Cancels the export.
     */
    private boolean cancelExport = false;
    /**
     * The chart panel containing the plot to export.
     */
    private ArrayList<ChartPanel> chartPanels;
    /**
     * The plot titles.
     */
    private ArrayList<String> plotTitles;
    /**
     * The MiTRAQ parent frame.
     */
    private MiTRAQ mitraq;

    /**
     * Create and open a new ExportPlot dialog.
     *
     * @param mitraq the parent frame
     * @param modal
     * @param chartPanels the chart panels containing the plots to export
     * @param plotTitles the plot titles 
     */
    public ExportPlot(MiTRAQ mitraq, boolean modal, ArrayList<ChartPanel> chartPanels, ArrayList<String> plotTitles) {
        super(mitraq, modal);
        this.chartPanels = chartPanels;
        this.plotTitles = plotTitles;
        this.mitraq = mitraq;
        initComponents();
        setLocationRelativeTo(mitraq);
        setVisible(true);
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        buttonGroup = new javax.swing.ButtonGroup();
        plottingTypeJPanel = new javax.swing.JPanel();
        pngJRadioButton = new javax.swing.JRadioButton();
        tiffJRadioButton = new javax.swing.JRadioButton();
        pdfJRadioButton = new javax.swing.JRadioButton();
        svgJRadioButton = new javax.swing.JRadioButton();
        exportJButton = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        setTitle("Export Plot");
        setResizable(false);

        plottingTypeJPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Plot Type"));

        buttonGroup.add(pngJRadioButton);
        pngJRadioButton.setSelected(true);
        pngJRadioButton.setText("PNG");
        pngJRadioButton.setIconTextGap(15);

        buttonGroup.add(tiffJRadioButton);
        tiffJRadioButton.setText("TIFF");
        tiffJRadioButton.setIconTextGap(15);

        buttonGroup.add(pdfJRadioButton);
        pdfJRadioButton.setText("PDF");
        pdfJRadioButton.setIconTextGap(15);

        buttonGroup.add(svgJRadioButton);
        svgJRadioButton.setText("SVG");
        svgJRadioButton.setIconTextGap(15);

        javax.swing.GroupLayout plottingTypeJPanelLayout = new javax.swing.GroupLayout(plottingTypeJPanel);
        plottingTypeJPanel.setLayout(plottingTypeJPanelLayout);
        plottingTypeJPanelLayout.setHorizontalGroup(
            plottingTypeJPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(plottingTypeJPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(plottingTypeJPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(svgJRadioButton)
                    .addComponent(pdfJRadioButton)
                    .addComponent(tiffJRadioButton)
                    .addComponent(pngJRadioButton))
                .addContainerGap(95, Short.MAX_VALUE))
        );
        plottingTypeJPanelLayout.setVerticalGroup(
            plottingTypeJPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(plottingTypeJPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(pngJRadioButton)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(tiffJRadioButton)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(pdfJRadioButton)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(svgJRadioButton)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        exportJButton.setText("Export");
        exportJButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                exportJButtonActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(exportJButton)
                    .addComponent(plottingTypeJPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(plottingTypeJPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(exportJButton)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    /**
     * Opens a file chooser where the user can select the file type to export
     * to. Then tries to export the plot to the selected format.
     *
     * @param evt
     */
    private void exportJButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_exportJButtonActionPerformed

        this.setVisible(false);

        final JFileChooser chooser = new JFileChooser(mitraq.getLastSelectedFolder());

        if (chartPanels.size() > 1) {
            chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
        }

        int selection = chooser.showSaveDialog(this);

        if (selection == JFileChooser.APPROVE_OPTION) {

            mitraq.setLastSelectedFolder(chooser.getCurrentDirectory().getAbsolutePath());

            if (chartPanels.size() > 1) {

                cancelExport = false;

                progressDialog = new ProgressDialog(this, this, true);

                new Thread(new Runnable() {
                    public void run() {
                        progressDialog.setIntermidiate(false);
                        progressDialog.setTitle("Exporting. Please Wait...");
                        progressDialog.setVisible(true);
                    }
                }, "ProgressDialog").start();

                new Thread("ExportThread") {
                    @Override
                    public void run() {

                        boolean makeDir = true;

                        if (!chooser.getSelectedFile().exists()) {
                            makeDir = chooser.getSelectedFile().mkdir();
                        }

                        if (makeDir) {

                            progressDialog.setMax(chartPanels.size());

                            for (int i = 0; i < chartPanels.size() && !cancelExport; i++) {
                                progressDialog.setValue(i + 1);
                                String title = plotTitles.get(i);
                                String selectedFile = chooser.getSelectedFile().getAbsolutePath() + File.separator + title;
                                saveChartPanel(chartPanels.get(i), selectedFile, false);
                            }

                            progressDialog.setVisible(false);
                            progressDialog.dispose();
                            JOptionPane.showMessageDialog(null, "Plots saved to " + chooser.getSelectedFile().getAbsolutePath(), "Plots Saved", JOptionPane.INFORMATION_MESSAGE);
                        } else {
                            progressDialog.setVisible(false);
                            progressDialog.dispose();
                            JOptionPane.showMessageDialog(null, "Failed to create folder " + chooser.getSelectedFile(), "Savong Error", JOptionPane.INFORMATION_MESSAGE);
                        }
                    }
                }.start();

            } else {

                progressDialog = new ProgressDialog(this, this, true);

                new Thread(new Runnable() {
                    public void run() {
                        progressDialog.setIntermidiate(false);
                        progressDialog.setTitle("Exporting. Please Wait...");
                        progressDialog.setVisible(true);
                    }
                }, "ProgressDialog").start();

                new Thread("ExportThread") {
                    @Override
                    public void run() {
                        String selectedFile = chooser.getSelectedFile().getAbsolutePath();
                        saveChartPanel(chartPanels.get(0), selectedFile, true);
                        progressDialog.setVisible(false);
                        progressDialog.dispose();
                    }
                }.start();
            }
        }

        mitraq.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
        this.dispose();
    }//GEN-LAST:event_exportJButtonActionPerformed
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.ButtonGroup buttonGroup;
    private javax.swing.JButton exportJButton;
    private javax.swing.JRadioButton pdfJRadioButton;
    private javax.swing.JPanel plottingTypeJPanel;
    private javax.swing.JRadioButton pngJRadioButton;
    private javax.swing.JRadioButton svgJRadioButton;
    private javax.swing.JRadioButton tiffJRadioButton;
    // End of variables declaration//GEN-END:variables

    /**
     * Exports the chart panel to the selected figure format.
     *
     * @param chartPanel the chart panel to export
     * @param selectedFile the file or folder to export the chart to
     * @param showSavedMessage if true, a message will be when the export is
     * complete
     */
    private void saveChartPanel(ChartPanel chartPanel, String selectedFile, boolean showSavedMessage) {

        try {

            if (pngJRadioButton.isSelected()) {
                if (!selectedFile.endsWith(ImageType.PNG.getExtension())) {
                    selectedFile += ImageType.PNG.getExtension();
                }
            } else if (tiffJRadioButton.isSelected()) {
                if (!selectedFile.endsWith(ImageType.TIFF.getExtension())) {
                    selectedFile += ImageType.TIFF.getExtension();
                }
            } else if (pdfJRadioButton.isSelected()) {
                if (!selectedFile.endsWith(ImageType.PDF.getExtension())) {
                    selectedFile += ImageType.PDF.getExtension();
                }
            } else if (svgJRadioButton.isSelected()) {
                if (!selectedFile.endsWith(ImageType.SVG.getExtension())) {
                    selectedFile += ImageType.SVG.getExtension();
                }
            }

            boolean saveFile = true;

            if (new File(selectedFile).exists()) {
                int option = JOptionPane.showConfirmDialog(this,
                        "The file " + selectedFile + " already exists. Overwrite?",
                        "Overwrite?", JOptionPane.YES_NO_CANCEL_OPTION);

                if (option != JOptionPane.YES_OPTION) {
                    saveFile = false;
                }
            }

            if (saveFile) {
                setCursor(new java.awt.Cursor(java.awt.Cursor.WAIT_CURSOR));
                mitraq.setCursor(new java.awt.Cursor(java.awt.Cursor.WAIT_CURSOR));

                ImageType currentImageType;

                if (pngJRadioButton.isSelected()) {
                    currentImageType = ImageType.PNG;
                } else if (tiffJRadioButton.isSelected()) {
                    currentImageType = ImageType.TIFF;
                } else if (pdfJRadioButton.isSelected()) {
                    currentImageType = ImageType.PDF;
                } else { // svg selected
                    currentImageType = ImageType.SVG;
                }

                Export.exportChart(chartPanel.getChart(), chartPanel.getBounds(), new File(selectedFile), currentImageType);

                setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
                mitraq.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));

                if (showSavedMessage) {
                    JOptionPane.showMessageDialog(this, "Plot saved to " + selectedFile, "Plot Saved", JOptionPane.INFORMATION_MESSAGE);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
            JOptionPane.showMessageDialog(this, "Unable to export plot: " + e.getMessage(), "Error Exporting Plot", JOptionPane.INFORMATION_MESSAGE);
        } catch (TranscoderException e) {
            e.printStackTrace();
            JOptionPane.showMessageDialog(this, "Unable to export plot: " + e.getMessage(), "Error Exporting Plot", JOptionPane.INFORMATION_MESSAGE);
        }
    }

    @Override
    public void cancelProgress() {
        cancelExport = true;
    }
}
